-- Asynchroniczna pamiec danych (RAM)
-- o pojemnosci 13 x 8 bitow
-- Wyjscie danych: DATAIN[7..0]
-- Wejscie danych: DATAOUT[7..0]
-- Wejscie adresu: ADDRESS[7..0]
-- Wejscia sterujace:
-- IE# (input enable)
-- OE# (output enable)

library IEEE; 
use IEEE.Std_Logic_1164.all;
use IEEE.Std_Logic_Arith.all;

entity RAM is
  generic (capacity    : integer := 13;
           word_length : integer := 8;
           filename    : string  := "data.txt.bin";
           delay       : time := 5 ns);
  
  port(ADDRESS : in std_logic_vector(3 downto 0);
       IE      : in std_logic;
       OE      : in std_logic;
       DATAIN  : in std_logic_vector(7 downto 0);
       DATAOUT : out std_logic_vector(7 downto 0));
       
  subtype word is bit_vector(7 downto 0);
  type rom_data_file_t is file of word;
end RAM;

architecture RAM_arch of RAM is
begin
  process(IE, OE, ADDRESS, DATAIN)  
    file rom_data_file : rom_data_file_t open read_mode is filename;
    type dtype is array (0 to capacity - 1) of word;
    variable rom_data : dtype;
    variable i : integer := 0;
    variable rom_init : boolean := false;
  begin
    -- jednokrotne wczytanie danych z pliku
    if (rom_init = false) then
      while not endfile(rom_data_file) and (i < capacity) loop
        read(rom_data_file, rom_data(i));
        i := i + 1;
      end loop;
      rom_init := true;
    end if;
    
      if (OE = '0') then
        DATAOUT <= to_StdLogicVector(rom_data(conv_integer(unsigned(ADDRESS)))) after delay;
      else
        DATAOUT <= "ZZZZZZZZ" after delay;
      end if;
    
      if (OE /= '0' and IE = '0') then
        rom_data(conv_integer(unsigned(ADDRESS))) := to_BitVector(DATAIN);
      end if;
  end process;
end RAM_arch;

